Iterators হল প্রোগ্রামিংয়ের একটি কৌশল, যা একটি সংকলন (যেমন অ্যারে বা হ্যাশ) বা ডেটা স্ট্রাকচারের উপর একে একে প্রবাহিত হতে পারে। রুবি ভাষায় custom iterators তৈরি করা একটি গুরুত্বপূর্ণ দক্ষতা, যা ব্যবহারকারীর প্রয়োজন অনুযায়ী একটি ডেটা স্ট্রাকচারের উপর কাস্টম লজিক প্রয়োগ করতে সহায়তা করে।
রুবিতে custom iterators তৈরি করতে, আপনি সাধারণত each বা অন্য কোনো ইটারেটর মেথড ব্যবহার করেন, যার মাধ্যমে আপনি ক্লাস বা মডিউলে ডাইনামিকভাবে একটি ইটারেটর তৈরি করতে পারেন।
১. Custom Iterator তৈরি করা
রুবিতে একটি custom iterator তৈরি করতে, আপনি একটি মেথড ব্যবহার করতে পারেন যা একটি ব্লক গ্রহণ করবে এবং সেই ব্লকের উপর প্রতিটি উপাদান প্রয়োগ করবে। রুবি প্রোগ্রামে, yield ব্যবহারের মাধ্যমে আপনি একটি ব্লক কল করতে পারেন এবং এটি ইটারেটর হিসেবে কাজ করতে পারে।
উদাহরণ:
ধরা যাক, আপনি একটি ক্লাস তৈরি করছেন যা একটি অ্যারে ইটারেট করবে।
class MyArray
def initialize(arr)
@arr = arr
end
# Custom iterator
def my_each
for element in @arr
yield element # Calling the block with each element
end
end
end
my_array = MyArray.new([1, 2, 3, 4, 5])
my_array.my_each do |num|
puts num * 2 # Output: 2, 4, 6, 8, 10
endএখানে, my_each মেথড একটি কাস্টম ইটারেটর তৈরি করেছে, যা অ্যারের প্রতিটি উপাদানকে ব্লকটির মধ্যে পাঠায় এবং ব্লকের মধ্যে ডিফাইন করা লজিক (এখানে num * 2) প্রয়োগ হয়।
২. Custom Iterator with Additional Logic
আপনি চাইলে আপনার কাস্টম ইটারেটরে অতিরিক্ত লজিক যোগ করতে পারেন। উদাহরণস্বরূপ, আপনি ইটারেটরের মধ্যে একটি শর্ত যোগ করতে পারেন, যাতে কিছু উপাদান বাদ দেওয়া যায় বা ফিল্টার করা যায়।
উদাহরণ:
class MyArray
def initialize(arr)
@arr = arr
end
# Custom iterator with filtering logic
def my_each_with_condition
for element in @arr
if element.even? # Only yield even numbers
yield element
end
end
end
end
my_array = MyArray.new([1, 2, 3, 4, 5])
my_array.my_each_with_condition do |num|
puts num # Output: 2, 4
endএখানে, my_each_with_condition কাস্টম ইটারেটরটি শুধু even numbers (যতগুলো সংখ্যা ২ দিয়ে ভাগ করা যায়) ব্লকে পাঠায় এবং সেগুলোর উপর অপারেশন প্রয়োগ করে।
৩. Using Enumerator for Custom Iterators
রুবি Enumerator ক্লাসও ব্যবহার করে কাস্টম ইটারেটর তৈরি করা যায়। এটি আপনাকে একটি lazy ইটারেটর প্রদান করে, যার মাধ্যমে শুধুমাত্র প্রয়োজনীয় উপাদানগুলি একে একে গেনারেট হয় এবং মেমরি দক্ষতার সাথে কাজ করা যায়।
উদাহরণ:
class MyArray
def initialize(arr)
@arr = arr
end
# Custom iterator using Enumerator
def my_each
Enumerator.new do |yielder|
@arr.each { |item| yielder << item }
end
end
end
my_array = MyArray.new([1, 2, 3, 4, 5])
enum = my_array.my_each
enum.each { |num| puts num * 2 } # Output: 2, 4, 6, 8, 10এখানে, my_each মেথড একটি Enumerator তৈরি করে এবং yielder অবজেক্ট ব্যবহার করে প্রতিটি উপাদান ব্লকে পাঠানো হয়। এটি একটি ইটারেটর হিসেবে কাজ করে এবং একে একে ডেটার উপর অপারেশন করে।
৪. Custom Iterator with Multiple Blocks
রুবিতে একটি মেথড একাধিক ব্লক গ্রহণ করতে পারে না, তবে আপনি যদি একাধিক প্রক্রিয়া একে একে চালাতে চান, তবে একাধিক ব্লকগুলি একসাথে নেয়ার জন্য proc বা lambda ব্যবহার করতে পারেন।
উদাহরণ:
class MyArray
def initialize(arr)
@arr = arr
end
# Custom iterator with two blocks
def my_each_with_two_blocks(proc1, proc2)
@arr.each do |element|
proc1.call(element)
proc2.call(element)
end
end
end
my_array = MyArray.new([1, 2, 3, 4, 5])
proc1 = Proc.new { |num| puts num * 2 } # Multiply by 2
proc2 = Proc.new { |num| puts num + 1 } # Add 1
my_array.my_each_with_two_blocks(proc1, proc2)
# Output:
# 2
# 2
# 4
# 3
# 6
# 4
# 8
# 5
# 10
# 6এখানে, দুটি আলাদা Proc তৈরি করা হয়েছে এবং my_each_with_two_blocks মেথডে দুটি ব্লক একে একে কল করা হচ্ছে।
৫. Advantages of Custom Iterators
- Code Reusability: একবার তৈরি করা হলে, কাস্টম ইটারেটর অন্যান্য কোডে পুনঃব্যবহারযোগ্য হয়, যেটি কোডের পুনঃব্যবহারযোগ্যতা বাড়ায়।
- Abstraction: কাস্টম ইটারেটর ডেটার উপর কাজ করার একটি সাধারণ পদ্ধতি তৈরি করে, যা কোডের অ্যাবস্ট্রাকশন উন্নত করে।
- Flexibility: আপনার কোডের মধ্যে dynamic behavior যোগ করতে, যেমন শর্ত বা ফিল্টারিং লজিক, যা সাধারণ ইটারেটর ব্যবহার করে সম্ভব নয়।
- Memory Efficiency: Enumerator ব্যবহার করে আপনি একটি lazy evaluation মেথড তৈরি করতে পারেন, যা শুধুমাত্র প্রয়োজনীয় উপাদানগুলো একে একে প্রসেস করে।
সারসংক্ষেপ
- Custom Iterators রুবিতে এমন একটি কৌশল যা ডেটার উপর dynamic behavior প্রয়োগ করতে সক্ষম করে এবং কোডের নমনীয়তা এবং পুনঃব্যবহারযোগ্যতা নিশ্চিত করে।
each,define_method,ProcএবংEnumeratorব্যবহার করে আপনি কাস্টম ইটারেটর তৈরি করতে পারেন।- কাস্টম ইটারেটরের মাধ্যমে আপনি filtering, sorting, mapping এবং accumulation এর মতো নানা ধরনের কাজ করতে পারেন।
এটি আপনার প্রোগ্রামিংয়ের দক্ষতা বাড়াতে সহায়ক হতে পারে এবং ডেটা ম্যানিপুলেশনকে আরও কার্যকর ও নমনীয় করে তোলে।
Read more